package com.atguigu.consumer.demo.config;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 消费者手动确认模式manual
 * channel.basicAck  手动确认
 * channel.basicNack  重试入列
 * channel.basicReject 直接拒绝
 *
 * @author Jia Fa
 * @create 2021-12-09 10:19
 */
@Component
public class RabbitConsumerConfig {

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "spring_test_queue", durable = "true"),  // 默认持久化,不需要指定durable
            exchange = @Exchange(value = "exchange_spring_topic"
                    , ignoreDeclarationExceptions = "true" // ignoreDeclarationExceptions 容错覆盖 忽略声明异常
                    , type = ExchangeTypes.TOPIC),
            key = {"a.b"}))
    public void listener(String msg, Channel channel, Message message) throws IOException {

        try {

            System.out.println("msg = " + msg);
            int i = 1 / 0;

            // 手动确认  投递的游标   是否同时确认多条消息(是否确认后面未确认的消息)
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
            // 获取重复投递的状态  如果重复投递则直接拒绝策略
            if (message.getMessageProperties().getRedelivered()) {
                // 直接拒绝  requeue 是否重新入队列
                //
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }


    }

    /**
     * 延时队列应当监视死信队列
     *
     * @param msg
     * @param channel
     * @param message
     */
    @RabbitListener(queues = "DEAD_QUEUE")
    public void listen(String msg, Channel channel, Message message) throws IOException {

        // 手动确认
        try {
            System.out.println("msg = " + msg);
//            int i = 1/0;
            // 游标  是否全部确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 判断是否进行过重返队列操作
            if (message.getMessageProperties().getRedelivered()){
                // 已经重试  直接拒绝
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            }else {
                // 尝试重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }
}
